Skip to content

Allow mode costs to vary by population segment - #405

Merged
FlxPo merged 1 commit into
mainfrom
feature/population-segment-utilities
Jul 31, 2026
Merged

Allow mode costs to vary by population segment#405
FlxPo merged 1 commit into
mainfrom
feature/population-segment-utilities

Conversation

@FlxPo

@FlxPo FlxPo commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Motivation

Transport behaviour does not use one set of mode-cost coefficients for every traveller. For example, pupils, households without cars, or residents of a policy area may have different constants, values of time, or distance costs. Until now, modelling that distinction required separate runs or ad hoc project code.

A naive implementation would also run destination and mode search once per population segment. That repeats shared preparation, scales with the number of demand subgroups, and becomes especially wasteful for partial-population assumptions. This PR represents distinct coefficient combinations as compact utility profiles and searches them together.

This PR is stacked on #404 and depends on:

Changes

  • Add PopulationSegment definitions to Population, with selectors for country, CSP, home zone, city category, and car ownership.
  • Add ParameterValue.by_population_segment() for mode cost constants, costs of time, and costs of distance; segment values can contain scenario and iteration values.
  • Support partial shares by splitting represented demand weight before applying max_persons_per_demand_subgroup.
  • Resolve the most specific matching segment and reject ambiguous or undefined configurations.
  • Deduplicate identical resolved coefficients into utility profiles.
  • Compute each distinct generalized-cost table once per iteration and reuse it across destination search, mode search, and final plan scoring.
  • Batch all profiles through the Rust destination and mode packages instead of running one model loop per segment.
  • Document the modeller-facing behavior in the population, run-parameter, and API guides.
  • Require version 0.1.1 of both Rust packages and invalidate affected destination/mode caches.

Example (if relevant)

population = mobility.Population(
    transport_zones,
    sample_size=1_000,
    population_segments=[
        mobility.PopulationSegment(name=pupils, csp=8a),
        mobility.PopulationSegment(
            name=localist_pupils,
            csp=8a,
            share=0.30,
        ),
    ],
)

pupil_cost = mobility.ParameterValue.by_population_segment(
    default=mobility.ParameterValue.by_iteration({1: 20.0, 5: 24.0}),
    segment_values={
        localist_pupils: mobility.ParameterValue.by_scenario(
            default=10.0,
            school_policy=8.0,
        )
    },
)

The 30% subgroup uses the segment value and the 70% complement keeps the default. Both remain in one model run.

AI-assisted contribution

Select one:

  • No AI assistance
  • AI used for minor help only (e.g. autocomplete, small refactors)
  • AI used for substantial parts of this PR

If substantial, briefly describe:

  • Scope of AI-assisted content: Public API, demand splitting, parameter resolution, cost-profile preparation, Rust integration, tests, and documentation.
  • What you reviewed or changed: Reviewed all three repository diffs for KISS, performance, cache correctness, validation behavior, documentation clarity, and unrelated project-specific files.
  • How you validated it (tests, checks, manual verification): 616 Mobility unit tests, 16 integration tests (1 skipped), warning-free Sphinx build, both Rust package suites and release Clippy, plus an end-to-end segmented model run.

Checklist

  • I have reviewed all code in this PR
  • I understand the code and can maintain it
  • I added or ran appropriate tests/checks for the changed behavior

@FlxPo
FlxPo requested a review from a team as a code owner July 31, 2026 17:40
@FlxPo

FlxPo commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Integration status: local validation is green with editable 0.1.1 builds of both dependency PRs (616 unit tests, 16 integration tests with 1 skipped, and a warning-free Sphinx build). The current Read the Docs failure is dependency ordering only: PyPI still exposes 0.1.0, so it cannot resolve mobility-mode-sequence-search==0.1.1 yet. Rerun hosted checks after the two package PRs are merged and tagged v0.1.1.

@FlxPo
FlxPo force-pushed the feature/population-segment-utilities branch from fa8b1e1 to 5674465 Compare July 31, 2026 18:54
@FlxPo
FlxPo changed the base branch from feature/destination-plan-search to main July 31, 2026 18:54
@FlxPo
FlxPo force-pushed the feature/population-segment-utilities branch from 5674465 to cae6430 Compare July 31, 2026 18:55
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.35664% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.20%. Comparing base (2b0949c) to head (cae6430).

Files with missing lines Patch % Lines
mobility/runtime/population_segments.py 94.56% 5 Missing ⚠️
...pool/detailed/detailed_carpool_generalized_cost.py 78.57% 3 Missing ⚠️
...trips/plans/mode_sequence_search/mode_sequences.py 83.33% 3 Missing ⚠️
mobility/runtime/parameter_values.py 85.71% 2 Missing ⚠️
mobility/transport/costs/transport_costs.py 96.29% 2 Missing ⚠️
...ips/group_day_trips/plans/destination_sequences.py 33.33% 2 Missing ⚠️
...ty/trips/group_day_trips/plans/demand_subgroups.py 96.00% 1 Missing ⚠️
...up_day_trips/plans/mode_sequence_search/prepare.py 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #405      +/-   ##
==========================================
+ Coverage   82.99%   83.20%   +0.21%     
==========================================
  Files         233      234       +1     
  Lines       16039    16294     +255     
==========================================
+ Hits        13312    13558     +246     
- Misses       2727     2736       +9     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@FlxPo
FlxPo merged commit d172ef4 into main Jul 31, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant